/*
 * @Author: greyqiu greyqiu@163.com
 * @Date: 2025-03-12 17:07:30
 * @LastEditors: greyqiu greyqiu@163.com
 * @LastEditTime: 2025-03-17 14:17:48
 * @Description: 
 * 本文件仅实现COM通信口的数据传输，不对收到的数据进行解析。
 * Copyright (c) 2025 by ${greyqiu}, All Rights Reserved. 
 */


#include "mb_transport.h"
#include "bsp.h"


void COM_objInit(MstObj *obj, uint8_t *pRx, uint16_t rxLen, uint8_t *pTx, uint16_t txLen, CallbackFunc handler, CallbackFunc timeoutCallback)
{
    obj->rxBuf = pRx;
    obj->rxBufSize = rxLen;
    obj->txBuf = pTx;
    obj->txBufSize = txLen;
    obj->timeOutTh = TIME_OUT_TH;
    obj->rxCallback = handler;
    obj->timeoutCallback = timeoutCallback;
}


void COM_rxProcess(MstObj *obj)
{

    obj->rxNum = obj->rxBufSize - DMA_Current_Data_Transfer_Number_Get(MB_RX_DMA_CH);
    if (obj->rxCallback != NULL && obj->rxNum > 0) {
        obj->rxCallback(obj->readAddr);
    }
    obj->txSta = MB_MST_IDLE;
    obj->rxNum = 0;
    obj->txNum = 0;
    obj->timeOutCnt = 0;
    obj->txSta = MB_MST_IDLE;
}


void COM_txProcess(MstObj *obj)
{
    uint16_t tmpLen;
    uint16_t err;
    switch (obj->txSta) {
        case MB_MST_IDLE:
            if (obj->txNum > 0) {
                obj->txSta = MB_MST_START;
                bsp_uart_send(obj->txBuf, obj->txNum); // 发送字节串
            };
            break;
        
        case MB_MST_START:
            if (bsp_uart_send_complete() == 1) {
                bsp_uart_dma_read_start(obj->rxBuf, obj->rxBufSize); // 开启DMA接收
                obj->timeOutCnt = 0;
                obj->txSta = MB_MST_WATI;

                obj->txNum = 0;
            };
            break;
        case MB_MST_WATI:
            tmpLen = obj->rxBufSize - DMA_Current_Data_Transfer_Number_Get(MB_RX_DMA_CH); // 计算当前DMA已经接收的字节数
            if (obj->rxNum != tmpLen) { // 通过判断字节数有无变化，复位空闲计数器
                obj->timeOutCnt = 0;
                obj->rxNum = tmpLen;
            }

            if (obj->timeOutCnt > 100) { // 接收空闲计数器超时，代表接收结束
                obj->timeOutCnt = 0;
                if (obj->rxNum > 0) { // 如完全无响应，则是对方响应超时错误
                    if (obj->rxCallback != NULL) {
                        err = obj->rxCallback(obj->readAddr);
                    }
                    obj->heartBeat = (err == 0);
                    obj->timeOutTimes = 0;
                } else {
                    obj->heartBeat = 0;
                    obj->timeOutTimes++;
                    if (obj->timeOutTimes > 2 && obj->timeoutCallback != NULL) {
                        err = obj->timeoutCallback(obj->readAddr);
                    }
                }
                bsp_uart_dma_read_stop();
                obj->txSta = MB_MST_IDLE;
//                bsp_uart_clear_error();
                
                bsp_uart_hmi_send(obj->rxBuf, obj->rxNum); // 转发给显示板.
                obj->timeOutCnt = 0;
                obj->rxNum = 0;
                obj->txNum = 0;
            };

            break;
        default:
            break;
    }

}
